package club.kynb.mall.application.context;

import club.kynb.mall.application.model.model.command.SubmitOrderCommand;
import club.kynb.mall.application.model.model.dto.*;
import club.kynb.mall.application.model.model.vo.OrderSubmitResultVO;
import club.kynb.mall.order.model.dto.OrderDTO;
import club.kynb.mall.order.model.dto.OrderDetailDTO;
import club.kynb.mall.product.dto.ProductSpuDetailDTO;
import club.kynb.mall.user.model.dto.ShippingAddressDTO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import lombok.Data;
import org.pizza.model.Model;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author kynb_club@163.com
 * @since 2021/7/5 4:58 下午
 */
@Data
public class OrderSubmitContext implements Model, OrderContext {
    /**
     * 快速失败标识
     */
    private boolean fastFailed = false;

    private SubmitOrderCommand command;

    private UserReceiveCouponDTO usedCoupon;

    private ShippingAddressDTO shippingAddress;
    /**
     * 预览的订单信息（外部的全部可见的属性）
     */
    private PreviewOrderDTO previewOrder;
    /**
     * 订单对应的spu对象（内部的包含了全部属性）
     */
    private List<ProductSpuDetailDTO> innerSpuList;
    /**
     * 最终下单的订单
     */
    private OrderDTO orderDTO = new OrderDTO();
    /**
     * 最终下单的订单详情
     */
    private List<OrderDetailDTO> orderDetailList = new ArrayList<>();
    /**
     * 提交订单结果
     */
    private OrderSubmitResultVO orderSubmitResultVO = new OrderSubmitResultVO();

    /**
     * 公共计算能力：计算累计总金额
     */
    public BigDecimal calculateTotalAmount(List<PreviewOrderSpuDTO> spuList) {
        if (CollectionUtil.isEmpty(spuList)) {
            return BigDecimal.ZERO;
        }
        //计算商品总价
        return spuList.stream().map(productSpuDTO -> {
            final PreviewOrderSkuDTO previewOrderSkuDTO = productSpuDTO.getPreviewOrderSkuDTO();
            final PreviewOrderSkuPriceDTO skuPriceDTO = previewOrderSkuDTO.getSkuPriceDTO();
            final Integer skuNum = previewOrderSkuDTO.getSkuNum();
            return NumberUtil.mul(skuPriceDTO.getSkuPrice(), new BigDecimal(String.valueOf(skuNum)));
        }).reduce(BigDecimal.ZERO, BigDecimal::add);
    }


}
